#include <rtthread.h>
#include "spi_sd.h"

#define DBG_TAG "drv_block_flash"
#define DBG_LVL DBG_ERROR
#include <rtdbg.h>

#define SECTOR_SIZE     (512)

struct block_sd_device
{
    struct rt_device                parent;      /**< RT-Thread device struct */
    struct rt_device_blk_geometry   geometry;    /**< sector size, sector count */
};

struct block_sd_device _block_device;

static rt_err_t block_sd_init(rt_device_t dev)
{
    SPI_SD_Init();

    return RT_EOK;
}

static rt_err_t block_sd_open(rt_device_t dev, rt_uint16_t oflag)
{
    struct block_sd_device *rtt_dev = (struct block_sd_device *)dev;
	rtt_dev->geometry.sector_count = SD_GetSectorCount();
	rt_kprintf("sector_count = %d\r\n",rtt_dev->geometry.sector_count);
    return RT_EOK;
}
static rt_err_t block_sd_close(rt_device_t dev)
{
    return RT_EOK;
}
static rt_size_t block_sd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    SD_ReadMultiBlock(pos, buffer, size);	
    return size;
}

static rt_size_t block_sd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    SD_WriteMultiBlock(pos, buffer, size);
    return size;
}

static rt_err_t block_sd_control(rt_device_t dev, int cmd, void *args)
{
    struct block_sd_device *rtt_dev = (struct block_sd_device *)dev;

    RT_ASSERT(dev != RT_NULL);

    if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
    {
        struct rt_device_blk_geometry *geometry;
        rt_kprintf("RT_DEVICE_CTRL_BLK_GETGEOME");

        geometry = (struct rt_device_blk_geometry *)args;
        if (geometry == RT_NULL) return -RT_ERROR;

        geometry->bytes_per_sector = rtt_dev->geometry.bytes_per_sector;
        geometry->block_size = rtt_dev->geometry.block_size;
        geometry->sector_count = rtt_dev->geometry.sector_count;
    }

    return RT_EOK;
}

int rt_hw_block_sd_init(void)
{
    rt_err_t result = RT_EOK;
	
    /* register sdcard device */
    _block_device.parent.type    = RT_Device_Class_Block;

    _block_device.geometry.bytes_per_sector = SECTOR_SIZE;
    _block_device.geometry.sector_count = 62488576;
    _block_device.geometry.block_size = SECTOR_SIZE;


    _block_device.parent.init    = block_sd_init;
    _block_device.parent.open    = block_sd_open;
    _block_device.parent.close   = block_sd_close;
    _block_device.parent.read    = block_sd_read;
    _block_device.parent.write   = block_sd_write;
    _block_device.parent.control = block_sd_control;

    /* no private, no callback */
    _block_device.parent.user_data = RT_NULL;
    _block_device.parent.rx_indicate = RT_NULL;
    _block_device.parent.tx_complete = RT_NULL;

    result = rt_device_register(&_block_device.parent, "sd0",
                                RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);

    return result;
}
INIT_DEVICE_EXPORT(rt_hw_block_sd_init);

